<template>
    <a-spin :spinning="loading" tip="加载中...">
        <div class="comment-container">
            <h2 class="comment-title" v-if="showTitle">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                    stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path
                        d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z">
                    </path>
                </svg>
                {{ title }}
            </h2>

            <!-- 评论表单 -->
            <form class="comment-form" @submit.prevent="addComment">
                <textarea v-model="newComment" class="comment-input" placeholder="分享你的想法..."></textarea>

                <div class="comment-tools">
                    <div class="left-tools">
                        <V3Emoji class="emoji-btn" :size="emojiSize" @click-emoji="onVue3Emoje" :recent="true"
                            :options-name="emojiOptionsName">
                        </V3Emoji>
                        <!-- 图片上传区域 -->
                        <div class="upload-img" style="display: flex;align-items: center;justify-content: center;">
                            <a-upload class="image-upload-area" v-model:file-list="fileList"
                                :customRequest="uploadImages"
                                :show-upload-list="{ showDownloadIcon: true, showRemoveIcon: true }" list-type="picture"
                                @remove="removeImage">
                                <svg t="1752628468607" class="icon" viewBox="0 0 1024 1024" version="1.1"
                                    style="font-size: 26px;" xmlns="http://www.w3.org/2000/svg" p-id="5684" width="200"
                                    height="200">
                                    <path
                                        d="M794.88 868.0448H232.8576c-72.448 0-131.1744-58.7264-131.1744-131.1744V277.8112c0-72.448 58.7264-131.1744 131.1744-131.1744h562.0224c72.448 0 131.1744 58.7264 131.1744 131.1744v459.1104c0 72.3968-58.7264 131.1232-131.1744 131.1232z"
                                        fill="#98E593" p-id="5685"></path>
                                    <path
                                        d="M340.3264 151.5008s-116.8896 23.3472-116.8896 122.88v192.256L108.1344 572.928V298.496c0-62.6176 9.728-170.3424 232.192-146.9952z"
                                        fill="#ADEFA8" p-id="5686"></path>
                                    <path
                                        d="M689.7152 151.7568s115.2 24.9344 115.2 131.072v205.056l113.6128 113.3568V308.5824c0-66.7136-9.6256-181.76-228.8128-156.8256z"
                                        fill="#86DB7F" p-id="5687"></path>
                                    <path
                                        d="M295.3216 152.2688S208.0768 189.184 208.0768 244.224s-2.56 229.9392-2.56 229.9392L282.624 393.5232V240.4864c0-33.9456 7.6288-64.1024 56.7808-84.4288 3.3792-12.0832-44.0832-3.7888-44.0832-3.7888z"
                                        fill="#CAF2C7" p-id="5688"></path>
                                    <path
                                        d="M926.0544 601.3952l-104.3968-83.0464c-31.488-25.088-76.6976-22.8864-105.6256 5.0688L359.424 868.0448h435.456c72.448 0 131.1744-58.7264 131.1744-131.1744v-135.4752z"
                                        fill="#FFD16C" p-id="5689"></path>
                                    <path
                                        d="M689.7152 858.5728s115.2-24.9344 115.2-131.072v-205.056l113.6128 63.2832v116.0192c0 66.7648-9.6256 181.76-228.8128 156.8256z"
                                        fill="#FFC50B" p-id="5690"></path>
                                    <path
                                        d="M794.88 893.6448H359.424c-10.4448 0-19.8144-6.3488-23.7568-16.0256-3.8912-9.6768-1.536-20.736 5.9392-28.0064l356.608-344.6272c38.0416-36.7616 97.9456-39.68 139.3664-6.7072l104.3968 83.0464c6.0928 4.864 9.6768 12.2368 9.6768 20.0192v135.4752c0 86.528-70.3488 156.8256-156.7744 156.8256z m-372.1216-51.2h372.1216c58.2144 0 105.5744-47.36 105.5744-105.5744v-123.136l-94.72-75.3664c-21.3504-16.9984-52.2752-15.5136-71.936 3.4816l-311.04 300.5952z"
                                        fill="#434A54" p-id="5691"></path>
                                    <path
                                        d="M399.9744 402.944c-30.7712-33.2288-82.944-34.3552-115.1488-2.56l-183.0912 180.7872v155.7504c0 72.448 58.7264 131.1744 131.1744 131.1744h562.0224c11.1616 0 22.016-1.3824 32.3584-4.0448L399.9744 402.944z"
                                        fill="#94E0DE" p-id="5692"></path>
                                    <path
                                        d="M340.3264 858.7776s-116.8896-23.3472-116.8896-122.88V466.6368l-115.3024 105.728v139.4176c0 62.5664 9.728 170.3424 232.192 146.9952z"
                                        fill="#B3F4EF" p-id="5693"></path>
                                    <path
                                        d="M295.3216 852.48s-87.2448-10.8032-87.2448-80.896c0-55.04-2.56-304.9472-2.56-304.9472l77.1072-54.272v351.8976c0 33.9456 7.6288 64.1024 56.7808 84.4288 3.3792 12.0832-44.0832 3.7888-44.0832 3.7888z"
                                        fill="#E9FFFF" p-id="5694"></path>
                                    <path
                                        d="M632.7296 353.4848m-74.6496 0a74.6496 74.6496 0 1 0 149.2992 0 74.6496 74.6496 0 1 0-149.2992 0Z"
                                        fill="#FFC50B" p-id="5695"></path>
                                    <path
                                        d="M621.9776 335.4112m-25.1904 0a25.1904 25.1904 0 1 0 50.3808 0 25.1904 25.1904 0 1 0-50.3808 0Z"
                                        fill="#FFE8C0" p-id="5696"></path>
                                    <path
                                        d="M794.88 121.0368H232.8576c-86.4256 0-156.7744 70.3488-156.7744 156.7744v459.1104c0 86.4256 70.3488 156.7744 156.7744 156.7744h562.2272c2.9696 0 5.888-0.1024 8.8064-0.256 0.9216-0.0512 1.792-0.1536 2.6624-0.2048 2.1504-0.1536 4.3008-0.3584 6.4-0.6144 0.9728-0.1024 1.9456-0.256 2.9696-0.3584 2.0992-0.3072 4.1984-0.6144 6.2464-0.9728 0.9216-0.1536 1.8432-0.3072 2.7648-0.512 2.4064-0.4608 4.7616-1.024 7.168-1.5872l1.3824-0.3072c0.0512 0 0.1024-0.0512 0.1536-0.0512 67.7376-17.3056 117.9648-78.848 117.9648-151.9104V277.8112c0.0512-86.4768-70.2976-156.7744-156.7232-156.7744zM232.8576 842.4448c-58.2144 0-105.5744-47.36-105.5744-105.5744V591.872l175.4624-173.2608c10.5984-10.496 24.7296-16.0256 39.5776-15.7184 14.8992 0.3072 28.672 6.5536 38.8096 17.4592l391.168 422.0928H232.8576z m667.5968-105.5744c0 44.0832-27.1872 81.8688-65.6384 97.6896L418.7136 385.536c-19.6608-21.1968-46.336-33.2288-75.264-33.8432-28.928-0.6656-56.1152 10.1888-76.6976 30.464l-139.52 137.728V277.8112c0-58.2144 47.36-105.5744 105.5744-105.5744h562.0224c58.2144 0 105.5744 47.36 105.5744 105.5744v459.0592z"
                                        fill="#434A54" p-id="5697"></path>
                                    <path
                                        d="M632.7296 253.2352c-55.2448 0-100.2496 44.9536-100.2496 100.2496 0 55.2448 44.9536 100.2496 100.2496 100.2496s100.2496-44.9536 100.2496-100.2496c-0.0512-55.2448-45.0048-100.2496-100.2496-100.2496z m0 149.2992c-27.0336 0-49.0496-22.016-49.0496-49.0496s22.016-49.0496 49.0496-49.0496 49.0496 22.016 49.0496 49.0496c-0.0512 27.0336-22.016 49.0496-49.0496 49.0496z"
                                        fill="#434A54" p-id="5698"></path>
                                </svg>
                                <template #removeIcon>
                                    <DeleteOutlined></DeleteOutlined>
                                </template>
                            </a-upload>
                        </div>
                    </div>

                    <div class="comment-btns">
                        <button type="submit" class="submit-btn">发布评论</button>
                    </div>
                </div>

            </form>

            <!-- 评论列表 -->
            <div class="comments-list">
                <CommentItem v-for="comment in comments" :key="comment.id" :comment="comment" @add-reply="addReply"
                    @onReply="onReply" :curReplyCommentId="curReplyCommentId" @sendCommentSub="sendCommentSub" />
            </div>

            <div class="load-more">
                <a-button v-if="hasMore" @click="loadMoreComments"><span class="load-more-txt">加载更多</span></a-button>
            </div>
            <div v-if="!hasMore" class="bottom-txt">到底啦~~</div>
        </div>
    </a-spin>
</template>

<script setup>
import { findCommentPageList, sendComment } from '@/api/comment.js';
import CommentItem from '@/components/CommentItem.vue';
import { DeleteOutlined, } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import axios from 'axios';
import { onMounted, reactive, ref, watch } from 'vue';
import V3Emoji from "vue3-emoji";
import { baseURL } from '../utils/request.js';
import { useUserStore } from '@/stores/user';

const props = defineProps({
    moduleId: {
        type: String,
        default: '',
    },
    title: {
        type: String,
        default: '',
    },
    showTitle: {
        type: Boolean,
        default: true,
    },
});
const emit = defineEmits(['sendComment']);
// 模块ID
const { moduleId } = props;
// 屏幕宽度
const windowWidth = ref(window.innerWidth);
// 文件列表
const fileList = ref([]);
// 当前登录用户信息
const currentUser = reactive({
    nickName: localStorage.getItem('nickName'),
    avatar: localStorage.getItem('avatar'),
});
const sendCommentSub = (val) => {
    if (val && val.commentId) {
        emit('sendComment', val);
    }
}
const userStore = useUserStore();
const loading = ref(false);
// 评论数据
const comments = ref([]);
// 新建评论
const newComment = ref('');
// 评论图片文件ID列表
const images = ref([]);
// 查询评论表单
const queryForm = reactive({
    pageModel: {
        pageNow: 1,
        pageSize: 10,
        query: {
            module_id1: '',
        },
        sort: ['1create_time'],
    }
});
// 是否还有更多评论
const hasMore = ref(true);
// emoji弹框大小
const emojiSize = ref('big');
// emoji选项卡中文配置
const emojiOptionsName = {
    'Smileys & Emotion': '笑脸&表情',
    'Food & Drink': '食物&饮料',
    'Animals & Nature': '动物&自然',
    'Travel & Places': '旅行&地点',
    'People & Body': '人物&身体',
    'Objects': '物品',
    'Symbols': '符号',
    'Flags': '旗帜',
    'Activities': '活动',
    'grinning face': '微笑',
}
// 限制最大上传5张图
const maxImages = 5;
// 单张图片最大20MB
const maxSize = 20 * 1024 * 1024;
// 允许的图片类型
const allowTypes = [
    'image/jpeg',   // JPG/JPEG
    'image/png',    // PNG
    'image/webp',   // WebP
    'image/gif',    // GIF（支持动态图）
    'image/bmp',    // BMP
    'image/tiff',   // TIFF
    'image/svg+xml' // SVG（矢量图）
];
// 图片类型友好名称映射（用于错误提示）
const allowedTypeNames = {
    'image/jpeg': 'JPG/JPEG',
    'image/png': 'PNG',
    'image/webp': 'WebP',
    'image/gif': 'GIF',
    'image/bmp': 'BMP',
    'image/tiff': 'TIFF',
    'image/svg+xml': 'SVG'
};
// 添加表情包
const onVue3Emoje = (val) => {
    newComment.value += val;
};
// 查找父评论
const findParentComment = (commentsList, parentId) => {
    for (const comment of commentsList) {
        if (comment.id === parentId) return comment;
    }
    return null;
};
// 当前回复的评论ID
const curReplyCommentId = ref(null);
const onReply = (comment) => {
    curReplyCommentId.value = comment ? comment.id : null;
};
// 添加回复（支持所有层级）
const addReply = (data) => {
    const { rootCommentId, content, toCommentId, toCommentUserId, imageFileIdList, fileList } = data;
    if (!content.trim() && fileList.length <= 0) return;
    // 找到父评论/回复
    const parent = findParentComment(comments.value, rootCommentId);
    if (parent) {
        // 确保父对象有replies数组
        if (!parent.replies) parent.replies = [];
        sendComment({
            content: content,
            toCommentId: toCommentId,
            toCommentUserId: parent.createUserId,
            rootCommentId: rootCommentId,
            imageFileIdList: imageFileIdList,
            moduleId: 1,
        }).then((res) => {
            if (res.code === 200) {
                emit('sendComment', { commentId: res.data.id })
                parent.replies.unshift({
                    id: res.data.id,
                    createUserNickname: currentUser.nickName,
                    avatar: currentUser.avatar,
                    createTime: res.data.createTime,
                    createUserId: res.data.createUserId,
                    content: content,
                    rootCommentId: parent.id,
                    toCommentId: toCommentId,
                    toCommentUserId: toCommentUserId,
                    imageList: fileList.map(e => e.url),
                    replies: [],
                });
            }
        }).catch(err => {
            console.log(err);
        });
    }
};

// 添加根评论
const addComment = () => {
    if (!localStorage.getItem('token')) {
        message.error('请先登录');
        return;
    }
    if (!newComment.value.trim() && fileList.value.length === 0) {
        message.error('评论内容不能为空');
        return;
    }

    let formData = {
        moduleId: moduleId,
        content: newComment.value,
        imageFileIdList: images.value,
    }

    sendComment(formData).then(res => {
        if (res.code == 200) {
            emit('sendComment', { commentId: res.data.id })
            comments.value.unshift({
                id: res.data.id,
                createUserNickname: currentUser.nickName,
                avatar: currentUser.avatar,
                createTime: res.data.createTime,
                content: newComment.value,
                createUserId: res.data.createUserId,
                city: res.data.city,
                likeCount: 0,
                dislikeCount: 0,
                images: images.value,
                imageList: fileList.value.map(e => e.url),
                replies: [],
            });
            images.value = [];
            newComment.value = '';
            fileList.value = [];
        }
    }).catch(err => { });
};
// 加载更多评论
const loadMoreComments = () => {
    queryForm.pageModel.pageNow++;
    findCommentData()
};

// 获取评论列表
const findCommentData = () => {
    loading.value = true;
    queryForm.pageModel.query.module_id1 = moduleId;
    findCommentPageList(queryForm).then(res => {
        if (res.code == 200) {
            let dataList = res.data.list.dataList ?? [];
            comments.value = [...comments.value, ...dataList];
            hasMore.value = res.data.list.total > comments.value.length;
            loading.value = false;
        }
    }).catch(err => {
    })
}

const handleScreenResize = () => {
    windowWidth.value = window.innerWidth;
    if (windowWidth.value < 768) {
        // 超小屏幕
        emojiSize.value = 'small';
    } else if (windowWidth.value < 992) {
        // 中等屏幕
        emojiSize.value = 'mid';
    } else if (windowWidth.value < 1200) {
        // 大屏幕
        emojiSize.value = 'big';
    } else {
        // 超大屏幕
        emojiSize.value = 'big';
    }
};

watch(() => props.moduleId, () => {
    if (props.moduleId) {
        findCommentData();
    }
});
onMounted(() => {
    // 监听屏幕尺寸变化
    window.addEventListener("resize", handleScreenResize);
    if (moduleId) {
        findCommentData();
    }
})

// 上传图片
const uploadImages = async ({ file }) => {
    if (!userStore.getToken) {
        message.error('请先登录！');
        fileList.value = [];
        return;
    }
    if (fileList.value.length > maxImages) {
        message.warn(`最多只能上传${maxImages}张图片`);
        return;
    }
    // 校验图片大小
    if (file.size > maxSize) {
        const sizeInMB = (maxSize / (1024 * 1024)).toFixed(1);
        message.warn(`图片大小不能超过${sizeInMB}MB`);
        return;
    }
    // 校验图片类型
    if (!allowTypes.includes(file.type)) {
        const allowedTypesText = allowTypes.map(type => allowedTypeNames[type] || type).join('、');
        message.warn(`请上传${allowedTypesText}格式的图片`);
        return; // 阻止上传
    }

    // 上传文件
    const formData = new FormData();
    formData.append('file', file);
    formData.append('moduleId', moduleId);
    const res = await axios.post(
        baseURL + 'lzh/file/upload2',
        formData,
        {
            headers: {
                'Content-Type': 'multipart/form-data',
                'token': localStorage.getItem('token'),
            },
        }
    );
    const fileInfo = res.data.data;
    if (res.data.code !== 200 || !fileInfo) {
        message.success("上传失败");
        return
    } else {
        message.success("上传成功");
        images.value.push(fileInfo.id);
        file.url = fileInfo.fileAddress;
        file.id = fileInfo.id;
        let newFileList = [];
        for (let i = 0; i < fileList.value.length; i++) {
            let one = fileList.value[i];
            if (!one.originFileObj) {
                newFileList.push(one)
            }
        }
        newFileList.push(file);
        fileList.value = [...newFileList];
    }
};

// 移除图片
const removeImage = (file) => {
    fileList.value = fileList.value.filter(item => item.uid !== file.uid);
    images.value = fileList.value.map(item => item.id);
};
</script>

<style scoped>
.comment-container {
    background-color: white;
    border-radius: 10px;
    padding: 20px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
    margin-bottom: 30px;


    .load-more {
        margin-top: 10px;
        text-align: center;

        .load-more-txt {
            color: #666;
        }

        button:hover .load-more-txt {
            color: #4285f4;
        }
    }

    .bottom-txt {
        text-align: center;
        color: #666;
        margin-top: 20px;
    }
}

.V3Emoji-vue-used-vue-type-style-index-0-lang-module__emojiItem___4NZ9O {
    width: auto;
}

.comment-title {
    font-size: 22px;
    margin-bottom: 20px;
    color: #333;
    display: flex;
    align-items: center;
    gap: 8px;

    svg {
        width: 24px;
        height: 24px;
        color: #4285f4;
    }
}

.comment-form {
    display: flex;
    flex-direction: column;
    gap: 15px;
    margin-bottom: 30px;

    .comment-tools {
        display: flex;
        justify-content: space-between;
        align-items: start;

        .left-tools {
            display: flex;

            .emoji-btn {
                margin-right: 10px;
            }

            .image-upload-area {
                cursor: pointer;
            }
        }
    }
}

.comment-input {
    padding: 12px 15px;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    resize: none;
    min-height: 100px;
    font-size: 15px;
    transition: border-color 0.3s;

    &:focus {
        outline: none;
        border-color: #4285f4;
    }
}

.comment-btns {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .comment-icon {
        font-size: 35px;
        cursor: pointer;
        fill: #979797;
        transition: 0.3s all linear;

        &:hover {
            fill: #4285f4;
        }
    }

    .submit-btn {
        padding: 10px 20px;
        background-color: #4285f4;
        color: white;
        border: none;
        border-radius: 6px;
        cursor: pointer;
        font-size: 15px;
        transition: background-color 0.3s;

        &:hover {
            background-color: #3367d6;
        }
    }

}


.comments-list {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-upload-wrapper :deep(.ant-upload-list) {
    display: flex;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-upload-wrapper :deep(.ant-upload-list) .ant-upload-list-item-container {
    margin-right: 10px;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-upload-wrapper :deep(.ant-upload-list) .ant-upload-list-item-container:last-child {
    margin-right: 0;
}

:where(.css-dev-only-do-not-override-1p3hq3p).ant-upload-wrapper {
    line-height: 0px;
}
</style>